<?php
namespace database;

use sql\SqlExec;
use PDO;

/*
	说明：
		1.在调用此函数前不能有任何输出操作。比如 echo print
		
	更新记录：
		2012-04-03 创建
		2014-08-11 更新数据库操作代码。 
*/
class DBFile
{
	var $db;//全局数据库连接,共用数据库连接
		
	function __construct() 
	{
		$this->db = new DbHelper();
	}

	/// <summary>
	/// 获取所有文件和文件夹列表，不包含子文件夹，包含已上传完的和未上传完的
	/// </summary>
	/// <param name="f_uid"></param>
	/// <returns></returns>
	static function GetAllUnComplete($f_uid)
	{
		$sql = "select 
				 f_id
				,f_uid
				,f_fdTask
				,f_nameLoc
				,f_pathLoc
				,f_pathSvr
				,f_md5
				,f_lenLoc
				,f_sizeLoc
				,f_pos
				,f_lenSvr
				,f_perSvr
				,f_complete
				 from up6_files
				 where f_uid=$f_uid and f_deleted=0 and f_fdChild=0 and f_complete=0 and f_scan=0;";//只加载未完成列表

		
		$se = new SqlExec();
		$data = $se->exec_arr("up6_files", $sql, "f_id,f_uid,f_fdTask,f_nameLoc,f_pathLoc,f_pathSvr,f_md5,f_lenLoc,f_sizeLoc,f_pos,f_lenSvr,f_perSvr,f_complete"
		    , "id,uid,fdTask,nameLoc,pathLoc,pathSvr,md5,lenLoc,sizeLoc,offset,lenSvr,perSvr,complete");
		
		return json_encode($data,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE);
	}
	
	function read($f_id, &$inf/*FileInf*/)
	{
		$ret = false;
		$sb = "select";
		$sb = $sb . " f_uid";
		$sb = $sb . ",f_nameLoc";
		$sb = $sb . ",f_nameSvr";
		$sb = $sb . ",f_pathLoc";
		$sb = $sb . ",f_pathSvr";
		$sb = $sb . ",f_pathRel";
		$sb = $sb . ",f_md5";
		$sb = $sb . ",f_lenLoc";
		$sb = $sb . ",f_sizeLoc";
		$sb = $sb . ",f_pos";
		$sb = $sb . ",f_lenSvr";
		$sb = $sb . ",f_perSvr";
		$sb = $sb . ",f_complete";
		$sb = $sb . ",f_time";
		$sb = $sb . ",f_deleted";
		$sb = $sb . " from up6_files";
		$sb = $sb . " where f_id=:f_id";
		$sb = $sb . " limit 0,1";
	
		$db = &$this->db;
	
		$cmd = $db->prepare_utf8($sb);
	
		$cmd->bindParam(":f_id", $f_id);
		$row = $db->ExecuteRow($cmd);
	
		if (!empty($row))
		{
			$inf->id 			= $f_id;
			$inf->uid 			= $row["f_uid"];
			$inf->nameLoc 		= $row["f_nameLoc"];
			$inf->nameSvr 		= $row["f_nameSvr"];
			$inf->pathLoc 		= $row["f_pathLoc"];
			$inf->pathSvr 		= $row["f_pathSvr"];
			$inf->pathRel 		= $row["f_pathRel"];
			$inf->md5 			= $row["f_md5"];
			$inf->lenLoc 		= intval($row["f_lenLoc"]);
			$inf->sizeLoc 		= $row["f_sizeLoc"];
			$inf->offset 		= intval($row["f_pos"]);
			$inf->lenSvr 		= intval($row["f_lenSvr"]);
			$inf->perSvr 		= $row["f_perSvr"];
			$inf->complete 		= (bool)$row["f_complete"];
			$inf->PostedTime 	= $row["f_time"];
			$inf->deleted 		= (bool)$row["f_deleted"];
			$ret = true;
		}
		return $ret;
	}

	/// <summary>
	/// 根据文件MD5获取文件信息
	/// 取已上传完的文件
	/// </summary>
	/// <param name="md5"></param>
	/// <param name="inf"></param>
	/// <returns></returns>
	function exist_file($md5, &$inf/*xdb_files*/)
	{
		$ret = false;
		$sb = "select * from (select ";
		$sb = $sb . "f_id";
		$sb = $sb . ",f_uid";
		$sb = $sb . ",f_nameLoc";
		$sb = $sb . ",f_nameSvr";
		$sb = $sb . ",f_pathLoc";
		$sb = $sb . ",f_pathSvr";
		$sb = $sb . ",f_pathRel";
		$sb = $sb . ",f_lenLoc";
		$sb = $sb . ",f_sizeLoc";
		$sb = $sb . ",f_pos";
		$sb = $sb . ",f_lenSvr";
		$sb = $sb . ",f_perSvr";
		$sb = $sb . ",f_complete";
		$sb = $sb . ",f_time";
		$sb = $sb . ",f_deleted";
		$sb = $sb . " from up6_files";
		$sb = $sb . " where f_md5=:f_md5";
		$sb = $sb . " and f_complete=1";
		$sb = $sb . " order by f_lenSvr desc";
		$sb = $sb . " ) tmp limit 1";

		$db = &$this->db;
		
		$cmd = $db->prepare_utf8($sb);
		
		$cmd->bindParam(":f_md5", $md5);
		$row = $db->ExecuteRow($cmd);		
		
		if (!empty($row))
		{
			$inf->id 			= $row["f_id"];
			$inf->uid 			= $row["f_uid"];
			$inf->nameLoc 		= $row["f_nameLoc"];
			$inf->nameSvr 		= $row["f_nameSvr"];
			$inf->pathLoc 		= $row["f_pathLoc"];
			$inf->pathSvr 		= $row["f_pathSvr"];
			$inf->pathRel 		= $row["f_pathRel"];
			$inf->md5 			= $md5;
			$inf->lenLoc 		= intval($row["f_lenLoc"]);
			$inf->sizeLoc 		= $row["f_sizeLoc"];
			$inf->offset 		= intval($row["f_pos"]);
			$inf->lenSvr 		= intval($row["f_lenSvr"]);
			$inf->perSvr 		= $row["f_perSvr"];
			$inf->complete 		= (bool)$row["f_complete"];
			$inf->PostedTime 	= $row["f_time"];
			$inf->deleted 		= (bool)$row["f_deleted"];
			$ret = true;
		}
		return $ret;
	}

	/// <summary>
	/// 增加一条数据，并返回新增数据的ID
	/// 在f_create.php中调用
	/// 文件名称，本地路径，远程路径，相对路径都使用原始字符串。
	/// d:\soft\QQ2012.exe
	/// </summary>
	function Add(&$model/*FileInf*/)
	{
	    $se = new SqlExec();
	    $se->insert("up6_files"
	        , array("f_id"=>$model->id
	        ,"f_sizeLoc"=>$model->sizeLoc
	        ,"f_perSvr"=>$model->perSvr
	        ,"f_complete"=>$model->complete
	        ,"f_fdTask"=>$model->fdTask
	        ,"f_fdChild"=>$model->fdChild
	        ,"f_uid"=>$model->uid
	        ,"f_nameLoc"=>$model->nameLoc
	        ,"f_nameSvr"=>$model->nameSvr
	        ,"f_pathLoc"=>$model->pathLoc
	        ,"f_pathSvr"=>$model->pathSvr
	        ,"f_pathRel"=>$model->pathRel
	        ,"f_md5"=>$model->md5
	        ,"f_lenLoc"=>$model->lenLoc
	        ,"f_pid"=>$model->pid
	        ,"f_pidRoot"=>$model->pidRoot	        
            ,"f_lenLocSec"=>$model->lenLocSec
            ,"f_blockSize"=>$model->blockSize
	        ,"f_blockSizeSec"=>$model->blockSizeSec
            ,"f_encrypt"=>$model->encrypt
	        ,"f_encryptAgo"=>$model->encryptAgo
	        ,"f_object_id"=>$model->getObjectID()
	    ));
	}

	static function Clear()
	{
		$db = new DbHelper();
		$db->ExecuteNonQueryTxt("TRUNCATE TABLE up6_files;");
		$db->ExecuteNonQueryTxt("TRUNCATE TABLE up6_folders;");
	}

	/// <summary>
	/// 
	/// </summary>
	/// <param name="f_uid"></param>
	/// <param name="f_id">文件ID</param>
	function fd_complete($idSvr)
	{
		$db = new DbHelper();
		$cmd =& $db->GetCommand("update up6_files set f_perSvr='100%',f_complete=1 where f_id=:f_id;");
		$cmd->bindParam(":f_id",$idSvr);
		$db->ExecuteNonQuery($cmd);
	}
	
	function fd_scan($id,$uid)
	{
		$sql = "update up6_files set f_scan=1 where f_id=:f_id and f_uid=:f_uid";
		$db = new DbHelper();
		$cmd =& $db->GetCommand($sql);
		
		$cmd->bindParam(":f_id", $id);
		$cmd->bindValue(":f_uid", $uid);
		$db->ExecuteNonQuery($cmd);
	}

	/// <summary>
	/// 更新上传进度
	/// </summary>
	///<param name="f_uid">用户ID</param>
	///<param name="f_id">文件ID</param>
	///<param name="f_pos">文件位置，大小可能超过2G，所以需要使用long保存</param>
	///<param name="f_lenSvr">已上传长度，文件大小可能超过2G，所以需要使用long保存</param>
	///<param name="f_perSvr">已上传百分比</param>
	function f_process($uid,$id,$offset,$lenSvr,$perSvr)
	{
		$sql = "update up6_files set f_pos=:pos,f_lenSvr=:len,f_perSvr=:per where f_uid=:uid and f_id=:id";		
		$db = &$this->db;
		$cmd =& $db->GetCommand($sql);
		
		$cmd->bindParam(":pos",$offset);
		$cmd->bindParam(":len",$lenSvr);
		$cmd->bindParam(":per",$perSvr);
		$cmd->bindParam(":uid",$uid);
		$cmd->bindParam(":id",$id);

		$db->ExecuteNonQuery($cmd);
		return true;
	}

	/// <summary>
	/// 上传完成。将所有相同MD5文件进度都设为100%
	/// </summary>
	function UploadComplete($md5)
	{
		$sql = "update up6_files set f_lenSvr=f_lenLoc,f_perSvr='100%',f_complete=1 where f_md5=:f_md5";
		$db = new DbHelper();
		$cmd =& $db->GetCommand($sql);
		
		$cmd->bindParam(":f_md5", $md5);
		$db->ExecuteNonQuery($cmd);
	}
	
	function complete($id)
	{
		$sql = "update up6_files set f_lenSvr=f_lenLoc,f_perSvr='100%',f_complete=1,f_scan=1 where f_id=:f_id";
		$db = new DbHelper();
		$cmd =& $db->GetCommand($sql);
	
		$cmd->bindParam(":f_id", $id);
		$db->ExecuteNonQuery($cmd);
	}

	/// <summary>
	/// 删除一条数据，并不真正删除，只更新删除标识。
	/// </summary>
	/// <param name="f_uid"></param>
	/// <param name="f_id"></param>
	function Delete($f_uid,$f_id)
	{
	    $se = new SqlExec();
	    $se->update2("up6_files", array("f_deleted"=>true), array("f_uid"=>$f_uid,"f_id"=>$f_id));
	}
	
	function del($pid,$name,$uid,$id)
	{
	    $sql = "update up6_files set f_deleted=1 where f_pid=:pid and f_nameLoc=:nameLoc and f_uid=:uid and f_id!=:f_id";
	    $db = new DbHelper();
	    $cmd =& $db->GetCommand($sql);
	
	    $cmd->bindParam(":pid", $pid);
	    $cmd->bindParam(":nameLoc", $name);
	    $cmd->bindParam(":uid", $uid);
	    $cmd->bindParam(":f_id", $id);
	    $db->ExecuteNonQuery($cmd);
	}

	function addBatch(/*List<FileInf>*/ $fs)
	{
		$sql = "insert into up6_files(".
						" f_id".
						",f_pid".
						",f_pidRoot".
						",f_sizeLoc".
						",f_lenLoc".
						",f_lenSvr".
						",f_perSvr".
						",f_complete".
						",f_time".
						",f_deleted".
						",f_scan".
						",f_fdTask".
						",f_fdChild".
						",f_uid".
						",f_nameLoc".
						",f_nameSvr".
						",f_pathLoc".
						",f_pathSvr".
						",f_pathRel".
						",f_md5".
						",f_lenLocSec".
						",f_encrypt".
						",f_encryptAgo".
						",f_blockSize".
						",f_blockSizeSec".
						",f_object_id".
						") values (".
						" :f_id".
						",:f_pid".
						",:f_pidRoot".
						",:f_sizeLoc".
						",:f_lenLoc".
						",:f_lenSvr".
						",'100%'".
						",1".
						",:f_time".
						",0".
						",1".
						",0".
						",1".
						",:f_uid".
						",:f_nameLoc".
						",:f_nameSvr".
						",:f_pathLoc".
						",:f_pathSvr".
						",:f_pathRel".
						",:f_md5".
						",:f_lenLocSec".
						",:f_encrypt".
						",:f_encryptAgo".
						",:f_blockSize".
						",:f_blockSizeSec".
						",:f_object_id".
						")";

		$db = new DbHelper();
		$cmd = $db->prepare_utf8($sql);
		
		foreach($fs as $f)
		{
			$cmd->bindParam(":f_id", $f->id);
			$cmd->bindParam(":f_pid", $f->pid);
			$cmd->bindParam(":f_pidRoot", $f->pidRoot);
			$cmd->bindParam(":f_sizeLoc", $f->sizeLoc);
			$cmd->bindParam(":f_lenLoc", $f->lenLoc);
			$cmd->bindParam(":f_lenSvr", $f->lenLoc);
			$cmd->bindValue(":f_time", $f->PostedTime);
			$cmd->bindParam(":f_uid", $f->uid);
			$cmd->bindParam(":f_nameLoc", $f->nameLoc);
			$cmd->bindParam(":f_nameSvr", $f->nameSvr);
			$cmd->bindParam(":f_pathLoc", $f->pathLoc);
			$cmd->bindParam(":f_pathSvr", $f->pathSvr);
			$cmd->bindParam(":f_pathRel", $f->pathRel);
			$cmd->bindParam(":f_md5", $f->md5);
			$cmd->bindParam(":f_lenLocSec", $f->lenLocSec);
			$cmd->bindParam(":f_encrypt", $f->encrypt,PDO::PARAM_BOOL);
			$cmd->bindParam(":f_encryptAgo", $f->encryptAgo);
			$cmd->bindParam(":f_blockSize", $f->blockSize);
			$cmd->bindParam(":f_blockSizeSec", $f->blockSizeSec);
			$cmd->bindValue(":f_object_id", $f->getObjectID());
			
			$db->ExecuteRow($cmd);
		}
	}
}
?>